﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Reflection;
using System.ServiceModel.DomainServices.Client;
using System.Windows;
using System.Windows.Browser;
using System.Windows.Controls;
using System.Windows.Threading;

using LogicStudio.Framework.UI.Comandos;
using Telerik.Windows.Controls;
using System.IO;
using System.Net;
using Biciq.Web.UI.Servicios;
using System.Threading;
using System.Globalization;
using System.Windows.Media;
using Telerik.Windows.Data;


namespace Biciq.Silverlight.UI
{
    public class VistaModeloBase:ViewModelBase
    {
        #region campos
        private bool _procesando;
        private List<ManejoError> _listaErrores;
        private Visibility _mostrarErrores;
        private string _tituloMensaje;
        private static BiciqAuthenticationContext _autenticacionContexto = new BiciqAuthenticationContext();

    
        private static SeguridadesDomainContext _seguridadesContexto = new SeguridadesDomainContext();
        private static BiciqDomainContext _biciqContexto = new BiciqDomainContext();
        private DomainContext _domainContext;

        private string _busqueda;

        private bool _esInicio;

        

     
        #endregion

        #region Propiedades


        /// <summary>
        /// Propiedad que indica si es la consulta inicial
        /// </summary>
        public bool EsInicio
        {
            get { return _esInicio; }
            set { _esInicio = value; }
        }

        /// <summary>
        /// Criterio de búsqueda
        /// </summary>
        public string Busqueda
        {
            get { return _busqueda; }
            set 
            { 
                _busqueda = value;
                RaisePropertyChanged("Busqueda");
            }
        }
        public static BiciqDomainContext BiciqContexto
        {
            get { return VistaModeloBase._biciqContexto; }
            set { VistaModeloBase._biciqContexto = value; }
        }

        /// <summary>
        /// 
        /// </summary>
        public static SeguridadesDomainContext SeguridadesContexto
        {
            get { return VistaModeloBase._seguridadesContexto; }
            set { VistaModeloBase._seguridadesContexto = value; }
        }
        /// <summary>
        /// 
        /// </summary>
        public static BiciqAuthenticationContext AutenticacionContexto
        {
            get { return VistaModeloBase._autenticacionContexto; }
            set { VistaModeloBase._autenticacionContexto = value; }
        }

        /// <summary>
        /// Indica si se esta procesando una petición del cliente
        /// </summary>
        public bool Procesando
        {
            get { return _procesando; }
            set
            {
                _procesando = value;
                RaisePropertyChanged("Procesando");
            }
        }
        /// <summary>
        /// Lista de Errores en la pantalla
        /// </summary>
        public List<ManejoError> ListaErrores
        {
            get { return _listaErrores; }
            set
            {
                _listaErrores = value;
                RaisePropertyChanged("ListaErrores");
            }
        }


        /// <summary>
        /// Indica se se deben o no mostrar los errores
        /// </summary>
        public Visibility MostrarErrores
        {
            get { return _mostrarErrores; }
            set
            {
                _mostrarErrores = value;
                RaisePropertyChanged("MostrarErrores");
            }
        }


        /// <summary>
        /// Titulo del mensaje en la pantalla de mensaje de error
        /// </summary>
        public string TituloMensaje
        {
            get { return _tituloMensaje; }
            set
            {
                _tituloMensaje = value;
                RaisePropertyChanged("TituloMensaje");
            }
        }

        #endregion

        #region Métodos Privados

        /// <summary>
        /// Método en el cual se valida los items econtrados en la búsqueda
        /// </summary>
        protected void validaBusqueda<T>(List<T> lista)
        {
            if (lista.Count == 0 && !this.EsInicio)
            {
                AgregarMensajeInformacion(string.Format(RecursosLenguaje.Recursos.BusquedaNoEncontrada));
                MostrarErrores = Visibility.Visible;
            }
            else
            {
                MostrarErrores = Visibility.Collapsed;

            }
            Busqueda = string.Empty;
            EsInicio = false;
        }
        public void InicializarMensajesError()
        {
            MostrarErrores = Visibility.Collapsed;
            ListaErrores = new List<ManejoError>();


        }

        public void AgregarMensajeError(string mensaje)
        {
            TituloMensaje = RecursosLenguaje.Recursos.TituloError;
            ManejoError error = new ManejoError(mensaje, RecursosLenguaje.Recursos.ImagenErrorPanel, RecursosLenguaje.Recursos.ColorError);
            ListaErrores.Add(error);

        }

        public void AgregarMensajeInformacion(string mensaje)
        {
            if (ListaErrores == null)
                ListaErrores = new List<ManejoError>();
            TituloMensaje = "Información";
            ManejoError error = new ManejoError(mensaje, RecursosLenguaje.Recursos.ImagenAdvertencia, RecursosLenguaje.Recursos.ColorAdvertencia);
            ListaErrores.Add(error);
        }

        protected void Cancelar(DomainContext domainContext)
        {
            if (IsDirty)
            {
                this._domainContext = domainContext;
                Action aceptar;
                aceptar = CancelarCambios;
                string titulo = string.Format(RecursosLenguaje.Recursos.Cancelar);
                LogicStudio.Framework.UI.Controles.CuadroDialogo.Mostrar(RecursosLenguaje.Recursos.MensajeCancelar, titulo, LogicStudio.Framework.UI.Utilidades.TipoVentana.Confirmar, aceptar);

            }
            else
            {
                CerrarVentana();
            }
        }

        protected void CerrarVentana()
        {
            if (EventoCerrarEditor != null)
            {
                EventoCerrarEditor(null, null);
            }
        }

        public virtual void CancelarCambios()
        {

            IsDirty = false;
            if (_domainContext != null)
                _domainContext.RejectChanges();
            IsDirty = false;
            CerrarVentana();

        }

        public List<ValidationResult> ValidarEntidadConMetadata(object entity, int? valorEntero = null)
        {
            List<ValidationResult> listaErrores = new List<ValidationResult>();


            var propiedades = entity.GetType().GetProperties();
            foreach (var item in propiedades)
            {

                var isNavigationProperty = (item.PropertyType == typeof(string)) ? false : item.PropertyType.GetInterfaces().Any(i => (i.IsGenericType && (i.GetGenericTypeDefinition() == typeof(IEnumerable<>))));

                if (!isNavigationProperty)
                {
                    if (item.PropertyType == typeof(string) && item.GetValue(entity, null) == null)
                        item.SetValue(entity, string.Empty, null);
                    var respuesta = Validator.TryValidateProperty(item.GetValue(entity, null), new ValidationContext(entity, null, null)
                    {
                        MemberName = item.Name

                    }, listaErrores
                        );


                }

            }

            listaErrores.ForEach(((Entity)entity).ValidationErrors.Add);

            return listaErrores;

        }

        
        #endregion

        #region Métodos Override
        public virtual void Buscar()
        {

        }
        public virtual void Limpiar()
        {

        }

        public virtual void Imprimir()
        {

        }
        public virtual void Guardar()
        {

        }

        public virtual void Nuevo()
        {
            
        }
        public virtual void Editar(object parametro)
        {

        }
        public virtual void Eliminar(object parametro)
        {

        }
        public virtual void Seleccionar(object parametro)
        {

        }
        public virtual void Cancelar()
        {
            if (IsDirty)
            {
                Action aceptar;
                aceptar = CancelarCambios;
                string titulo = string.Format(RecursosLenguaje.Recursos.Cancelar);
                LogicStudio.Framework.UI.Controles.CuadroDialogo.Mostrar(RecursosLenguaje.Recursos.MensajeCancelar, titulo, LogicStudio.Framework.UI.Utilidades.TipoVentana.Confirmar, aceptar);

            }
            else
            {
                CerrarVentana();
            }
        }
        
        #endregion

        #region Comandos
        protected RelayCommand _comandoBuscar;
        private RelayCommand _comandoEliminar;
        private RelayCommand _comandoNuevo;
        private RelayCommand _comandoEditar;
        private RelayCommand _comandoSeleccionar;
        protected RelayCommand _comandoCancelar;
        private RelayCommand _comandoGuardar;
        private RelayCommand _comandoCerrarMensaje;
        private RelayCommand _comandoExportarExcel;

        public RelayCommand ComandoExportarExcel
        {
            get
            {
                return _comandoExportarExcel ?? (_comandoExportarExcel = new RelayCommand(Export));
            }
        }

        public RelayCommand ComandoCerrarMensaje
        {
            get
            {
                if (_comandoCerrarMensaje == null)
                {
                    _comandoCerrarMensaje = new RelayCommand
                    (
                        p => InicializarMensajesError()
                    );
                }
                return _comandoCerrarMensaje;
            }
        }


        /// <summary>
        /// Comando Buscar
        /// </summary>
        public RelayCommand ComandoBuscar
        {
            get
            {
                if (_comandoBuscar == null)
                {
                    _comandoBuscar = new RelayCommand
                    (
                        p => Buscar()
                    );
                }
                return _comandoBuscar;
            }
        }

        /// <summary>
        /// Comando Guardar
        /// </summary>
        public RelayCommand ComandoGuardar
        {
            get
            {
                if (_comandoGuardar == null)
                {
                    _comandoGuardar = new RelayCommand
                    (
                        p => Guardar()
                    );
                }
                return _comandoGuardar;
            }
        }
        /// <summary>
        /// Comando que dispara la ventana para creación de un nuevo registro
        /// </summary>
        public RelayCommand ComandoNuevo
        {
            get
            {
                if (_comandoNuevo == null)
                {
                    _comandoNuevo = new RelayCommand
                    (
                        p => Nuevo()
                    );
                }
                return _comandoNuevo;
            }
        }
        /// <summary>
        /// Comando Cancelar
        /// </summary>
        public RelayCommand ComandoCancelar
        {
            get
            {
                if (_comandoCancelar == null)
                {
                    _comandoCancelar = new RelayCommand
                    (
                        p => Cancelar()
                    );
                }
                return _comandoCancelar;
            }
        }
        /// <summary>
        /// Comando que dispara la ventana para edición de un registro
        /// </summary>
        public RelayCommand ComandoEditar
        {
            get
            {
                return _comandoEditar ?? (_comandoEditar = new RelayCommand(Editar));
            }
        }

        /// <summary>
        /// Comando que dispara la ventana para edición de un registro
        /// </summary>
        public RelayCommand ComandoEliminar
        {
            get
            {
                return _comandoEliminar ?? (_comandoEliminar = new RelayCommand(Eliminar));
            }
        }

        /// <summary>
        /// Comando que dispara la ventana para edición de un registro
        /// </summary>
        public RelayCommand ComandoSeleccionar
        {
            get
            {
                return _comandoSeleccionar ?? (_comandoSeleccionar = new RelayCommand(Seleccionar));
            }
        }
        #endregion

        #region COnstructores
        public VistaModeloBase()
        {
            Thread.CurrentThread.CurrentCulture = new CultureInfo("es-EC");
            Thread.CurrentThread.CurrentUICulture = new CultureInfo("es-EC");
            Thread.CurrentThread.CurrentCulture.DateTimeFormat.ShortDatePattern = "dd/MM/yyyy";
        }
        #endregion

        #region eventos
        public EventHandler EventoCerrarEditor;
 
        #endregion

        #region Exportar


        public void Export(object parameter)
        {
            RadGridView grid = parameter as RadGridView;
            if (grid != null)
            {
                grid.ElementExporting -= this.ElementExporting;
                grid.ElementExporting += this.ElementExporting;

                string extension = "xls";
                ExportFormat format = ExportFormat.Html;

             

                SaveFileDialog dialog = new SaveFileDialog();
                dialog.DefaultExt = extension;
                dialog.Filter = String.Format("{1} files (*.{0})|*.{0}|All files (*.*)|*.*", extension, "Excel" );
                dialog.FilterIndex = 1;

                if (dialog.ShowDialog() == true)
                {
                    using (Stream stream = dialog.OpenFile())
                    {
                        GridViewExportOptions exportOptions = new GridViewExportOptions();
                        exportOptions.Format = format;
                        exportOptions.ShowColumnFooters = true;
                        exportOptions.ShowColumnHeaders = true;
                        exportOptions.ShowGroupFooters = true;

                        grid.Export(stream, exportOptions);
                    }
                }
            }
        }
        private void ElementExporting(object sender, GridViewElementExportingEventArgs e)
        {
            if (e.Element == ExportElement.HeaderRow || e.Element == ExportElement.FooterRow
                || e.Element == ExportElement.GroupFooterRow)
            {
                e.Background = Colors.LightGray;
                e.Foreground = Colors.Black;
                e.FontSize = 20;
                e.FontWeight = FontWeights.Bold;
            }
            else if (e.Element == ExportElement.Row)
            {
                e.Background = Colors.White;
                e.Foreground = Colors.Black;
            }
            else if (e.Element == ExportElement.Cell &&
                e.Value != null && e.Value.Equals("Chocolade"))
            {
                e.FontFamily = new FontFamily("Verdana");
                e.Background = Colors.LightGray;
                e.Foreground = Colors.Blue;
            }
            else if (e.Element == ExportElement.GroupHeaderRow)
            {
                e.FontFamily = new FontFamily("Verdana");
                e.Background = Colors.LightGray;
                e.Height = 30;
            }
            else if (e.Element == ExportElement.GroupHeaderCell &&
                e.Value != null && e.Value.Equals("Chocolade"))
            {
                e.Value = "MyNewValue";
            }
            else if (e.Element == ExportElement.GroupFooterCell)
            {
                GridViewDataColumn column = e.Context as GridViewDataColumn;
                QueryableCollectionViewGroup qcvGroup = e.Value as QueryableCollectionViewGroup;

                if (column != null && qcvGroup != null && column.AggregateFunctions.Count() > 0)
                {
                    e.Value = GetAggregates(qcvGroup, column);
                }
            }
        }
        private string GetAggregates(QueryableCollectionViewGroup group, GridViewDataColumn column)
        {
            List<string> aggregates = new List<string>();

            foreach (AggregateFunction f in column.AggregateFunctions)
            {
                foreach (AggregateResult r in group.AggregateResults)
                {
                    if (f.FunctionName == r.FunctionName && r.FormattedValue != null)
                    {
                        aggregates.Add(r.FormattedValue.ToString());
                    }
                }
            }

            return String.Join(",", aggregates.ToArray());
        }
        #endregion
    }
}
